package Client;

import Factory.BootstrapFactory;
import Factory.ListenerFactory;
import callback.ListenerCallback;
import handler.HttpHandler;
import handler.TcpHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import sys.Console;

import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class Client {

    private static Console console = Console.getInstance();

    private final InetSocketAddress tcpAddress;
    private final InetSocketAddress httpAddress;

    private final HashedWheelTimer RECONNECT_TIMER = new HashedWheelTimer();

    private Bootstrap tcpBootstrap;

    private Bootstrap httpBootstrap;

    private static Client client;

    private ChannelFuture tcpFuture;

    private ChannelFuture httpFuture;


    private Client(InetSocketAddress tcpAddress, InetSocketAddress httpAddress) {
        this.tcpAddress = tcpAddress;
        this.httpAddress = httpAddress;
    }

    public static Client getInstance() {
        synchronized (Client.class) {
            if (client == null) {
                // 服务器地址
                InetSocketAddress tcpAddress = new InetSocketAddress("localhost", 18848);
                // 本地地址
                InetSocketAddress httpAddress = new InetSocketAddress("localhost", 8000);
                client = new Client(tcpAddress, httpAddress);
            }
            return client;
        }
    }

    public void httpConnect(ChannelFutureListener channelFutureListener) throws InterruptedException {
        this.httpBootstrap.connect().sync().addListener(channelFutureListener);
    }

    public void httpConnect() throws InterruptedException {
        this.httpBootstrap.connect().sync();
    }

    public void tcpConnect() throws InterruptedException {
        this.tcpBootstrap.connect().sync().addListener(ListenerFactory.getDefaultListener("tcp 连接成功"));
    }

    public void init() throws Exception {
        List<ChannelHandler> tcpList = new ArrayList<>();
        tcpList.add(new TcpHandler());
        this.tcpBootstrap = BootstrapFactory.getTcpBootstrap(tcpList, this.tcpAddress);
        List<ChannelHandler> list = new ArrayList<>();
        list.add(new HttpHandler());
        this.httpBootstrap = BootstrapFactory.getHttpBootstrap(list, this.httpAddress);
    }

    public void start() throws Exception {
        if (this.httpBootstrap == null || this.tcpBootstrap == null) {
            throw new RuntimeException("please call the init() method first");
        }
        try {
            this.httpFuture = this.httpBootstrap.connect().sync().addListener(ListenerFactory.getDefaultListener("http-连接成功"));
            this.tcpFuture = this.tcpBootstrap.connect().sync().addListener(ListenerFactory.getDefaultListener("server-连接成功")); // 阻塞等待远程节点连接完成
            this.httpFuture.channel().closeFuture();
            this.tcpFuture.channel().closeFuture().sync(); // 阻塞等待远程节点关闭
        } finally {
            this.tcpBootstrap.group().shutdownGracefully().sync();
            this.httpBootstrap.group().shutdownGracefully().sync();
        }
    }
}
